﻿// ## 2023/09/09 # 黑店小小二 # 小城兼容处理 ##
// ## 2023/05/07 # 江东新风 # 特技常数函数替换 ##
// ## 2023/04/25 # 江东新风 # 取消特技转特效 ##
// ## 2022/03/28 # 江东新风 # 俘虏概率调整 ##
// ## 2022/03/17 # 江东新风 # 府兵空指针bug ##
// ## 2022/02/15 # 江东新风 # 府兵无法俘虏 ##
// ## 2021/10/28 # 江东新风 # 单港关存活设定变更 ##
// ## 2021/10/01 # 江东新风 # namespace的韩文改成英文 ##
// ## 2021/09/15 # 江东新风 # 更改pk::core[]函数为英文##
// ## 2021/03/12 # 江东新风 # 用retfunc解决单港关俘虏释放后在野问题 ##
// ## 2021/02/18 # 江东新风 # 尝试修复单港关bug ##
// ## 2021/02/17 # 江东新风 # 修复空指针错误 ##
// ## 2021/02/08 # 江东新风 # 解决单港关，部队被灭武将在野的问题，修正任务外出武将的所属问题 ##
// ## 2021/01/24 # 江东新风 # 解决单港关，最后城被攻陷的武将变在野问题 ##
// ## 2021/01/14 # 江东新风 # 关掉trace ##
// ## 2020/12/29 # 江东新风 # 临时将普通武将的最终捕获率调整为原来的50% ##
// ## 2020/12/26 # 江东新风 # 关掉trace ##
// ## 2020/12/12 # 江东新风 # 修复trace参数报错 ##
// ## 2020/09/15 #江东新风#大幅降低君主被俘虏概率，临时武将(农民兵，突袭者)不可捕获##
// ## 2020/08/16 #江东新风#has_skill函数替換##
namespace CAPTURE_CHANCE
{
	array<array<int>> 单城被灭武将;
	int base_id;
	int kunshu_id;
	class Main
	{
		Main()
		{
			pk::set_func(220, pk::func220_t(callback));
		}

		void callback(const pk::destroy_info& in info, pk::list<pk::person@>& captured, pk::list<pk::person@>& escaped, bool tactics_bonus)
		{
			//pk::trace(pk::format("计算俘虏概率",1));

			pk::hex_object@ attacker = info.attacker;
			pk::hex_object@ target = info.target;

			int attacker_force_id = attacker.get_force_id();
			int target_force_id = target.get_force_id();
			pk::building@ attacker_building = attacker.get_type_id() == pk::building::type_id ? attacker : null;
			pk::unit@ attacker_unit = attacker.get_type_id() == pk::unit::type_id ? attacker : null;
			pk::building@ target_building = target.get_type_id() == pk::building::type_id ? target : null;
			pk::unit@ target_unit = target.get_type_id() == pk::unit::type_id ? target : null;
			int target_border_radius = pk::is_alive(target_building) and target_building.facility == 设施_都市 ? 2 : 1;
			pk::point attacker_pos = attacker.get_pos();
			pk::point target_pos = target.get_pos();
			bool in_border = pk::is_in_range(target_pos, target_border_radius, attacker_pos);
			bool cant_capture = !pk::is_valid_normal_force_id(attacker_force_id) or !pk::is_valid_normal_force_id(target_force_id);
			bool penalty = pk::get_scenario().difficulty == 难易度_超级 and attacker.is_player() and not target.is_player();
			bool has_hobaku_skill = false;
			int hobaku_chance = 0;
			int target_building_id_t = -1;
			pk::list<pk::person@> prisoner_list;
			//为单港关存活加的城市数量计数


			// 공격 오브젝트의 포박 특기 보유 확인确认攻击对象的特技
			if (pk::is_alive(attacker_unit))
			{
				has_hobaku_skill = in_border and ch::has_skill(attacker_unit, 特技_擒拿);
				hobaku_chance = pk::core::skill_constant_value(特技_擒拿);
				cant_capture = cant_capture or !pk::is_normal_person(attacker_unit.leader);//加入如果攻击方是非正常武将，则无法进行捕获
			}
			else if (pk::is_alive(attacker_building))
			{
				int building_id = attacker_building.get_id();
				int hex_object_id = pk::building_id_to_hex_object_id(building_id);
				pk::list<pk::person@> list = pk::get_person_list(hex_object_id, pk::mibun_flags(身份_君主, 身份_都督, 身份_太守, 身份_一般));
				pk::filter_list(list, 무장속성_세력, attacker_force_id, COMPARE_EQ);

				if (list.size == 0)
					cant_capture = true;

				if (in_border)
				{
					for (int i = 0; i < list.size; i++)
					{
						if (ch::has_skill(list[i], 特技_擒拿))
						{
							has_hobaku_skill = true;
							hobaku_chance = pk::max(hobaku_chance, pk::core::skill_constant_value(特技_擒拿));
						}
					}
				}
			}

			// 목표 오브젝트 무장 확인确认目标对象的武将
			if (pk::is_alive(target_unit))
			{
				for (int i = 0; i < 3; i++)
				{
					pk::person@ member = pk::get_person(target_unit.member[i]);
					if (pk::is_alive(member))
						prisoner_list.push_back(member);
				}
			}
			else if (pk::is_alive(target_building))
			{
				int building_id = target_building.get_id();
				target_building_id_t = building_id;
				int hex_object_id = pk::building_id_to_hex_object_id(building_id);
				prisoner_list = pk::get_person_list(hex_object_id, pk::mibun_flags(身份_君主, 身份_都督, 身份_太守, 身份_一般));
				pk::filter_list(prisoner_list, 무장속성_세력, target_force_id, COMPARE_EQ);

			}

			int bordered_unit_count = 0;
			int terrain_id = -1;

			if (pk::is_valid_pos(target_pos))
			{
				array<pk::point>@ range = pk::range(target_pos, 0, target_border_radius);
				for (int i = 0; i < int(range.length); i++)
				{
					pk::unit@ unit = pk::get_unit(range[i]);
					if (pk::is_alive(unit) and unit.get_force_id() == attacker_force_id)
						bordered_unit_count++;
				}
				terrain_id = pk::get_hex(target_pos).terrain;
			}


			for (int i = 0; i < prisoner_list.size; i++)
			{
				pk::person@ person = prisoner_list[i];
				if (cant_capture)
				{
					escaped.push_back(person);
					continue;
				}

				if (not info.releasable)
				{
					if (!(pk::is_kunshu(person) and pk::get_city_count(pk::get_force(target_force_id)) == 0))
					{
						captured.push_back(person);
						continue;
					}
					
				}
				
				if (pk::has_item(person, 보물종류_명마) or ch::has_skill(person, 特技_幸运))
				{
					escaped.push_back(person);
					continue;
				}

				int n = 0;
#if param_set
				n += pk::get_stat_param().max_stat + 20 - pk::max(person.stat[武将能力_武力], person.stat[武将能力_智力]);
#endif
#if not_param_set
				n += int(pk::core["person.max_stat"]) + 20 - pk::max(person.stat[武将能力_武力], person.stat[武将能力_智力]);
#endif
				
				n /= 3;
				if (bordered_unit_count > 0)
					n *= 100 * (ch::has_skill(person, 特技_铁壁) ? 1 : bordered_unit_count);
				if (terrain_id == 地形_湿地 or terrain_id == 地形_毒泉)
					n = int(n * 1.5f);
				n /= 100;
				if (tactics_bonus)
					n += 10;
				n /= penalty ? 2 : 1;
				n += has_hobaku_skill ? hobaku_chance : 0;


				//君主捕缚率为十分之一
				if (pk::is_kunshu(person))
				{
					n /= 10;
				}
					
				//临时武将(农民兵，突袭者，府兵)不可捕缚
				if (ch::is_临时武将(person.get_id()))
					n = 0;

				n = int(pk::max(0, pk::min(n, 100)));
				// pk::trace(pk::format("person id:{};capture chance:{}",person.get_id(),n));
				if (pk::rand_bool(n))
					captured.push_back(person);
				else
					escaped.push_back(person);

			}
		}

	}

	Main main;
}